#include <iostream>
#include <memory>
#include <functional>
#include <vector>   
#include <unordered_map>
#include <cstdint>
#include <unistd.h>

using TaskFunc = std::function<void()>;
using ReleaseFunc = std::function<void()>;
class TimerTask{
public:
    TimerTask(uint64_t id, uint32_t delay, const TaskFunc& callback)
        :_id(id)
        ,_timeout(delay)
        ,_taskcallback(callback)
        ,_canceled(false)
    {}

    void SetRelease(const ReleaseFunc& releasecallback)
    {
        _release = releasecallback;
    }

    uint32_t DelayTime(){
        return _timeout;
    }

    void Cancel()
    {
        _canceled = true;
    }

    ~TimerTask()
    {
        if (_canceled == false)
        {
            _taskcallback();   
        }
        _release();
    }
private:
    uint64_t _id;               // 定时器任务对象ID
    uint32_t _timeout;          // 定时任务的超时时间
    bool _canceled;             // false 表示没有被取消，true表示被取消
    TaskFunc _taskcallback;     // 定时器对象要执行的定时任务
    ReleaseFunc _release;       // 用于删除TimeWheel中保存的定时器对象信息
};

class TimerWheel{
public:
    TimerWheel()
        :_capacity(60)
        ,_tick(0)
        ,_wheel(_capacity)
    {}

    void TimerAdd(int64_t id, uint32_t delay, const TaskFunc& callback)
    {
        ptrTask pt(new TimerTask(id, delay, callback));
        pt->SetRelease(std::bind(&TimerWheel::RemoveTimer, this, id));
        _timers[id] = weakTask(pt);
        int pos = (_tick + delay) % _capacity;
        _wheel[pos].push_back(pt);
    }

    void TimerRefresh(uint64_t id)
    {
        // 通过保存的定时器对象的 weak_ptr构造一个shared_ptr出来
        auto it = _timers.find(id);
        if (it == _timers.end())
        {
            std::cout << "没找到定时任务" << std::endl;
            return;
        }
        ptrTask pt = it->second.lock(); //lock获取weak_ptr管理的对象对应的shared_ptr
        int delay = pt->DelayTime();
        int pos = (_tick + delay) % _capacity;
        _wheel[pos].push_back(pt);
    }

    void TimerCancel(uint64_t id)
    {
        auto it = _timers.find(id);
        if (it == _timers.end())
        {
            std::cout << "没找到定时任务" << std::endl;
            return;
        }
        ptrTask pt = it->second.lock(); 
        if (pt)
        {
            pt->Cancel();
        }
        
    }

    void RunTimerTask()
    {
        _tick = (_tick + 1) % _capacity;
        _wheel[_tick].clear();
    }
private:
    void RemoveTimer(uint64_t id)
    {
        auto it = _timers.find(id);
        if (it != _timers.end())
        {
            _timers.erase(it);
        }
    }
private:
    using weakTask = std::weak_ptr<TimerTask>;
    using ptrTask = std::shared_ptr<TimerTask>;
    int _tick;          // 当前的秒针，走到哪里就释放哪里，
    int _capacity;      // 表盘最大数量 -- 最大延迟时间
    std::vector<std::vector<ptrTask>> _wheel;
    std::unordered_map<uint64_t, weakTask> _timers;   
};

class Test{
public:
    Test(){
        std::cout << "构造" << std::endl;
    }
    ~Test(){
        std::cout << "析构" << std::endl;
    }
};

void Deltest(Test * t)
{
    delete t;
}

int main()
{
    TimerWheel tw;
    Test * t = new Test();

    tw.TimerAdd(12345, 5, std::bind(Deltest, t));

    for (int i = 0; i < 5; i++)
    {
        sleep(1);
        tw.TimerRefresh(12345);  // 刷新定时任务
        tw.RunTimerTask();       // 向后移动指针
        std::cout << "刷新定时任务，需要5秒才销毁" << std::endl;
    }
    tw.TimerCancel(12345);

    while (1)
    {
        sleep(1);
        std::cout << "------------------------" << std::endl;
        tw.RunTimerTask();
    }
    
}

